home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / wnos / wn941101 / lapb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-10  |  43.5 KB  |  1,674 lines

  1. /* @(#) $Header: lapb.c,v 1.20 92/01/12 18:40:08 deyke Exp $ */
  2.  
  3. /* Link Access Procedures Balanced (LAPB), the upper sublayer of
  4.  * AX.25 Level 2.
  5.  */
  6. #include <time.h>
  7. #include "global.h"
  8. #include "mbuf.h"
  9. #include "timer.h"
  10. #include "ax25.h"
  11. #include "lapb.h"
  12. #include "netrom.h"
  13. #include "asy.h"
  14. #include "cmdparse.h"
  15. #include "netuser.h"
  16.  
  17. extern struct ax25_cb *netrom_server_axcb;
  18.  
  19. char  *ax25states[] = {
  20.   "Disconnected",
  21.   "Conn pending",
  22.   "Connected",
  23.   "Disc pending"
  24. };
  25.  
  26. char  *ax25reasons[] = {
  27.   "Normal",
  28.   "Reset",
  29.   "Timeout",
  30.   "Network"
  31. };
  32.  
  33. int  ax_maxframe =      7;      /* Transmit flow control level */
  34. int  ax_paclen   =    236;      /* Maximum outbound packet size */
  35. int  ax_pthresh  =     64;      /* Send polls for packets larger than this */
  36. int  ax_retry    =     10;      /* Retry limit */
  37. int32 ax_t1init  =   5000;      /* Retransmission timeout */
  38. int32 ax_t2init  =   2000;      /* Acknowledgement delay timeout */
  39. int32 ax_t3init  = 900000;      /* No-activity timeout */
  40. int32 ax_t4init  =  60000;      /* Busy timeout */
  41. int32 ax_t5init  =   1000;      /* Packet assembly timeout */
  42. int  ax_window   =   2048;      /* Local flow control limit */
  43. struct ax25_cb *axcb_server;    /* Server control block */
  44.  
  45. static struct ax25_cb *axcb_head;
  46.  
  47. static int is_flexnet __ARGS((char *call, int store));
  48. static void reset_t1 __ARGS((struct ax25_cb *cp));
  49. static void inc_t1 __ARGS((struct ax25_cb *cp));
  50. static void send_packet __ARGS((struct ax25_cb *cp, int type, int cmdrsp, struct mbuf *data));
  51. static int busy __ARGS((struct ax25_cb *cp));
  52. static void send_ack __ARGS((struct ax25_cb *cp, int cmdrsp));
  53. static void try_send __ARGS((struct ax25_cb *cp, int fill_sndq));
  54. static void setaxstate __ARGS((struct ax25_cb *cp, int newstate));
  55. static void t1_timeout __ARGS((struct ax25_cb *cp));
  56. static void t2_timeout __ARGS((struct ax25_cb *cp));
  57. static void t3_timeout __ARGS((struct ax25_cb *cp));
  58. static void t4_timeout __ARGS((struct ax25_cb *cp));
  59. static void t5_timeout __ARGS((struct ax25_cb *cp));
  60. static struct ax25_cb *create_axcb __ARGS((struct ax25_cb *prototype));
  61. static void build_path __ARGS((struct ax25_cb *cp, struct iface *ifp, struct ax25 *hdr, int reverse));
  62. static int put_reseq __ARGS((struct ax25_cb *cp, struct mbuf *bp, int ns));
  63. static int dodigipeat __ARGS((int argc, char *argv [], void *p));
  64. static int domaxframe __ARGS((int argc, char *argv [], void *p));
  65. static int domycall __ARGS((int argc, char *argv [], void *p));
  66. static int dopaclen __ARGS((int argc, char *argv [], void *p));
  67. static int dopthresh __ARGS((int argc, char *argv [], void *p));
  68. static int doaxreset __ARGS((int argc, char *argv [], void *p));
  69. static int doretry __ARGS((int argc, char *argv [], void *p));
  70. static int dorouteadd __ARGS((int argc, char *argv [], void *p));
  71. static void doroutelistentry __ARGS((struct ax_route *rp));
  72. static int doroutelist __ARGS((int argc, char *argv [], void *p));
  73. static int doroutestat __ARGS((int argc, char *argv [], void *p));
  74. static int doaxroute __ARGS((int argc, char *argv [], void *p));
  75. static int doaxstatus __ARGS((int argc, char *argv [], void *p));
  76. static int dot1 __ARGS((int argc, char *argv [], void *p));
  77. static int dot2 __ARGS((int argc, char *argv [], void *p));
  78. static int dot3 __ARGS((int argc, char *argv [], void *p));
  79. static int dot4 __ARGS((int argc, char *argv [], void *p));
  80. static int dot5 __ARGS((int argc, char *argv [], void *p));
  81. static int doaxwindow __ARGS((int argc, char *argv [], void *p));
  82.  
  83. /*---------------------------------------------------------------------------*/
  84.  
  85. static int is_flexnet(call, store)
  86. char *call;
  87. int store;
  88. {
  89.  
  90. #define FTABLESIZE 23
  91.  
  92.   struct ftable_t {
  93.     struct ftable_t *next;
  94.     char call[AXALEN];
  95.   };
  96.  
  97.   char *cp;
  98.   long hashval;
  99.   static struct ftable_t *ftable[FTABLESIZE];
  100.   struct ftable_t **tp;
  101.   struct ftable_t *p;
  102.  
  103.   cp = call;
  104.   hashval  = ((*cp++ << 23) & 0x0f000000);
  105.   hashval |= ((*cp++ << 19) & 0x00f00000);
  106.   hashval |= ((*cp++ << 15) & 0x000f0000);
  107.   hashval |= ((*cp++ << 11) & 0x0000f000);
  108.   hashval |= ((*cp++ <<  7) & 0x00000f00);
  109.   hashval |= ((*cp++ <<  3) & 0x000000f0);
  110.   hashval |= ((*cp   >>  1) & 0x0000000f);
  111.   tp = ftable + (hashval % FTABLESIZE);
  112.   for (p = *tp; p && !addreq(p->call, call); p = p->next) ;
  113.   if (!p && store) {
  114.     p = malloc(sizeof(*p));
  115.     addrcp(p->call, call);
  116.     p->next = *tp;
  117.     *tp = p;
  118.   }
  119.   return (int) (p != 0);
  120. }
  121.  
  122. /*---------------------------------------------------------------------------*/
  123.  
  124. static void reset_t1(cp)
  125. struct ax25_cb *cp;
  126. {
  127.   int32 tmp;
  128.  
  129.   tmp = cp->srtt + 4 * cp->mdev;
  130.   if (tmp < 500) tmp = 500;
  131.   set_timer(&cp->timer_t1, tmp);
  132. }
  133.  
  134. /*---------------------------------------------------------------------------*/
  135.  
  136. static void inc_t1(cp)
  137. struct ax25_cb *cp;
  138. {
  139.   int32 tmp;
  140.  
  141.   tmp = (dur_timer(&cp->timer_t1) * 5 + 2) / 4;
  142.   if (tmp > 10 * cp->srtt) tmp = 10 * cp->srtt;
  143.   if (tmp < 500) tmp = 500;
  144.   set_timer(&cp->timer_t1, tmp);
  145. }
  146.  
  147. /*---------------------------------------------------------------------------*/
  148.  
  149. #define next_seq(n)  (((n) + 1) & 7)
  150.  
  151. /*---------------------------------------------------------------------------*/
  152.  
  153. static void send_packet(cp, type, cmdrsp, data)
  154. struct ax25_cb *cp;
  155. int  type;
  156. int  cmdrsp;
  157. struct mbuf *data;
  158. {
  159.  
  160.   int  control;
  161.   struct mbuf *bp;
  162.  
  163.   if (cp->mode == STREAM && (type == I || type == UI)) {
  164.     if (!(bp = pushdown(data, 1))) {
  165.       free_p(data);
  166.       return;
  167.     }
  168.     *bp->data = PID_NO_L3;
  169.     data = bp;
  170.   }
  171.  
  172.   control = type;
  173.   if (type == I) {
  174.     control |= (cp->vs << 1);
  175.     cp->vs = next_seq(cp->vs);
  176.   }
  177.   if ((type & 3) != U) {
  178.     control |= (cp->vr << 5);
  179.     stop_timer(&cp->timer_t2);
  180.   }
  181.   if (cmdrsp & PF) control |= PF;
  182.   if (!(bp = pushdown(data, 1))) {
  183.     free_p(data);
  184.     return;
  185.   }
  186.   *bp->data = control;
  187.   data = bp;
  188.  
  189.   if (cmdrsp & DST_C)
  190.     cp->hdr.cmdrsp = LAPB_COMMAND;
  191.   else if (cmdrsp & SRC_C)
  192.     cp->hdr.cmdrsp = LAPB_RESPONSE;
  193.   else
  194.     cp->hdr.cmdrsp = VERS1;
  195.   if (!(bp = htonax25(&cp->hdr, data))) {
  196.     free_p(data);
  197.     return;
  198.   }
  199.   data = bp;
  200.  
  201.   if (type == RR || type == REJ || type == UA) cp->rnrsent = 0;
  202.   if (type == RNR) cp->rnrsent = 1;
  203.   if (type == REJ) cp->rejsent = 1;
  204.   if (cmdrsp == POLL) cp->polling = 1;
  205.   if (type == I || cmdrsp == POLL) start_timer(&cp->timer_t1);
  206.  
  207.   axroute(cp, data);
  208. }
  209.  
  210. /*---------------------------------------------------------------------------*/
  211.  
  212. static int  busy(cp)
  213. struct ax25_cb *cp;
  214. {
  215.   return cp->peer ? space_ax(cp->peer) <= 0 : cp->rcvcnt >= ax_window;
  216. }
  217.  
  218. /*---------------------------------------------------------------------------*/
  219.  
  220. static void send_ack(cp, cmdrsp)
  221. struct ax25_cb *cp;
  222. int  cmdrsp;
  223. {
  224.   if (busy(cp))
  225.     send_packet(cp, RNR, cmdrsp, NULLBUF);
  226.   else if (!cp->rejsent && (cp->reseq[0].bp || cp->reseq[1].bp ||
  227.                             cp->reseq[2].bp || cp->reseq[3].bp ||
  228.                             cp->reseq[4].bp || cp->reseq[5].bp ||
  229.                             cp->reseq[6].bp || cp->reseq[7].bp))
  230.     send_packet(cp, REJ, cmdrsp, NULLBUF);
  231.   else
  232.     send_packet(cp, RR, cmdrsp, NULLBUF);
  233. }
  234.  
  235. /*---------------------------------------------------------------------------*/
  236.  
  237. static void try_send(cp, fill_sndq)
  238. struct ax25_cb *cp;
  239. int  fill_sndq;
  240. {
  241.  
  242.   int  cnt;
  243.   struct mbuf *bp;
  244.  
  245.   stop_timer(&cp->timer_t5);
  246.   while (cp->unack < cp->cwind) {
  247.     if (cp->state != CONNECTED || cp->remote_busy) return;
  248.     if (fill_sndq && cp->t_upcall) {
  249.       cnt = space_ax(cp);
  250.       if (cnt > 0) {
  251.         (*cp->t_upcall)(cp, cnt);
  252.         if (cp->unack >= cp->cwind) return;
  253.       }
  254.     }
  255.     if (!cp->sndq) return;
  256.     if (cp->mode == STREAM) {
  257.       cnt = len_p(cp->sndq);
  258.       if (cnt < ax_paclen) {
  259.         if (cp->unack) return;
  260.         if (!cp->peer && cp->sndqtime + ax_t5init - msclock() > 0) {
  261.           set_timer(&cp->timer_t5, cp->sndqtime + ax_t5init - msclock());
  262.           start_timer(&cp->timer_t5);
  263.           return;
  264.         }
  265.       }
  266.       if (cnt > ax_paclen) cnt = ax_paclen;
  267.       if (!(bp = alloc_mbuf(cnt))) return;
  268.       pullup(&cp->sndq, bp->data, bp->cnt = cnt);
  269.     } else {
  270.       bp = dequeue(&cp->sndq);
  271.     }
  272.     enqueue(&cp->resndq, bp);
  273.     cp->unack++;
  274.     cp->sndtime[cp->vs] = msclock();
  275.     dup_p(&bp, bp, 0, MAXINT16);
  276.     send_packet(cp, I, CMD, bp);
  277.   }
  278. }
  279.  
  280. /*---------------------------------------------------------------------------*/
  281.  
  282. static void setaxstate(cp, newstate)
  283. struct ax25_cb *cp;
  284. int  newstate;
  285. {
  286.   int  oldstate;
  287.  
  288.   oldstate = cp->state;
  289.   cp->state = newstate;
  290.   cp->polling = 0;
  291.   cp->retry = 0;
  292.   stop_timer(&cp->timer_t1);
  293.   stop_timer(&cp->timer_t2);
  294.   stop_timer(&cp->timer_t4);
  295.   stop_timer(&cp->timer_t5);
  296.   reset_t1(cp);
  297.   switch (newstate) {
  298.   case DISCONNECTED:
  299.     if (cp->peer) close_ax(cp->peer);
  300.     if (cp->s_upcall) (*cp->s_upcall)(cp, oldstate, newstate);
  301.     if (cp->peer && cp->peer->state == DISCONNECTED) {
  302.       del_ax(cp->peer);
  303.       del_ax(cp);
  304.     }
  305.     break;
  306.   case CONNECTING:
  307.     if (cp->s_upcall) (*cp->s_upcall)(cp, oldstate, newstate);
  308.     send_packet(cp, SABM, POLL, NULLBUF);
  309.     break;
  310.   case CONNECTED:
  311.     if (cp->peer && cp->peer->state == DISCONNECTED) {
  312.       send_packet(cp->peer, UA, FINAL, NULLBUF);
  313.       setaxstate(cp->peer, CONNECTED);
  314.     }
  315.     if (cp->s_upcall) (*cp->s_upcall)(cp, oldstate, newstate);
  316.     try_send(cp, 1);
  317.     break;
  318.   case DISCONNECTING:
  319.     if (cp->peer) close_ax(cp->peer);
  320.     if (cp->s_upcall) (*cp->s_upcall)(cp, oldstate, newstate);
  321.     send_packet(cp, DISC, POLL, NULLBUF);
  322.     break;
  323.   }
  324. }
  325.  
  326. /*---------------------------------------------------------------------------*/
  327.  
  328. static void t1_timeout(cp)
  329. struct ax25_cb *cp;
  330. {
  331.   inc_t1(cp);
  332.   cp->cwind = 1;
  333.   if (++cp->retry > ax_retry) cp->reason = TIMEOUT;
  334.   switch (cp->state) {
  335.   case DISCONNECTED:
  336.     break;
  337.   case CONNECTING:
  338.     if (cp->peer && cp->peer->state == DISCONNECTED)
  339.       if (cp->retry > 2)
  340.         setaxstate(cp, DISCONNECTED);
  341.       else
  342.         start_timer(&cp->timer_t1);
  343.     else if (cp->retry > ax_retry)
  344.       setaxstate(cp, DISCONNECTED);
  345.     else
  346.       send_packet(cp, SABM, POLL, NULLBUF);
  347.     break;
  348.   case CONNECTED:
  349.     if (cp->retry > ax_retry) {
  350.       setaxstate(cp, DISCONNECTING);
  351.     } else if (!cp->polling && !cp->remote_busy && cp->unack &&
  352.                len_p(cp->resndq) <= ax_pthresh) {
  353.       int  old_vs;
  354.       struct mbuf *bp;
  355.       old_vs = cp->vs;
  356.       cp->vs = (cp->vs - cp->unack) & 7;
  357.       cp->sndtime[cp->vs] = 0;
  358.       dup_p(&bp, cp->resndq, 0, MAXINT16);
  359.       send_packet(cp, I, POLL, bp);
  360.       cp->vs = old_vs;
  361.     } else {
  362.       send_ack(cp, POLL);
  363.     }
  364.     break;
  365.   case DISCONNECTING:
  366.     if (cp->retry > ax_retry)
  367.       setaxstate(cp, DISCONNECTED);
  368.     else
  369.       send_packet(cp, DISC, POLL, NULLBUF);
  370.     break;
  371.   }
  372. }
  373.  
  374. /*---------------------------------------------------------------------------*/
  375.  
  376. static void t2_timeout(cp)
  377. struct ax25_cb *cp;
  378. {
  379.   send_ack(cp, RESP);
  380. }
  381.  
  382. /*---------------------------------------------------------------------------*/
  383.  
  384. static void t3_timeout(cp)
  385. struct ax25_cb *cp;
  386. {
  387.   if (!run_timer(&cp->timer_t1)) send_ack(cp, POLL);
  388. }
  389.  
  390. /*---------------------------------------------------------------------------*/
  391.  
  392. static void t4_timeout(cp)
  393. struct ax25_cb *cp;
  394. {
  395.   if (!cp->polling) send_ack(cp, POLL);
  396. }
  397.  
  398. /*---------------------------------------------------------------------------*/
  399.  
  400. static void t5_timeout(cp)
  401. struct ax25_cb *cp;
  402. {
  403.   try_send(cp, 1);
  404. }
  405.  
  406. /*---------------------------------------------------------------------------*/
  407.  
  408. static struct ax25_cb *create_axcb(prototype)
  409. struct ax25_cb *prototype;
  410. {
  411.   struct ax25_cb *cp;
  412.  
  413.   if (prototype) {
  414.     cp = (struct ax25_cb *) malloc(sizeof(struct ax25_cb ));
  415.     *cp = *prototype;
  416.   } else
  417.     cp = (struct ax25_cb *) cxallocw(1, sizeof(struct ax25_cb ));
  418.   cp->cwind = 1;
  419.   cp->timer_t1.func = (void (*)()) t1_timeout;
  420.   cp->timer_t1.arg = cp;
  421.   cp->timer_t2.func = (void (*)()) t2_timeout;
  422.   cp->timer_t2.arg = cp;
  423.   cp->timer_t3.func = (void (*)()) t3_timeout;
  424.   cp->timer_t3.arg = cp;
  425.   cp->timer_t4.func = (void (*)()) t4_timeout;
  426.   cp->timer_t4.arg = cp;
  427.   cp->timer_t5.func = (void (*)()) t5_timeout;
  428.   cp->timer_t5.arg = cp;
  429.   cp->next = axcb_head;
  430.   return axcb_head = cp;
  431. }
  432.  
  433. /*---------------------------------------------------------------------------*/
  434.  
  435. static void build_path(cp, ifp, hdr, reverse)
  436. struct ax25_cb *cp;
  437. struct iface *ifp;
  438. struct ax25 *hdr;
  439. int  reverse;
  440. {
  441.  
  442.   char  *dest;
  443.   int  d;
  444.   int  i;
  445.   struct ax_route *rp;
  446.  
  447.   if (reverse) {
  448.  
  449.     /*** copy hdr into control block ***/
  450.  
  451.     addrcp(cp->hdr.dest, hdr->source);
  452.     addrcp(cp->hdr.source, hdr->dest);
  453.     for (i = 0; i < hdr->ndigis; i++)
  454.       addrcp(cp->hdr.digis[i], hdr->digis[hdr->ndigis-1-i]);
  455.     cp->hdr.ndigis = hdr->ndigis;
  456.  
  457.     /*** find my last address ***/
  458.  
  459.     cp->hdr.nextdigi = 0;
  460.     for (i = 0; i < cp->hdr.ndigis; i++)
  461.       if (ismyax25addr(cp->hdr.digis[i])) cp->hdr.nextdigi = i + 1;
  462.  
  463.     cp->ifp = ifp;
  464.  
  465.   } else {
  466.  
  467.     /*** copy hdr into control block ***/
  468.  
  469.     cp->hdr = *hdr;
  470.  
  471.     /*** find my last address ***/
  472.  
  473.     cp->hdr.nextdigi = 0;
  474.     for (i = 0; i < cp->hdr.ndigis; i++)
  475.       if (ismyax25addr(cp->hdr.digis[i])) cp->hdr.nextdigi = i + 1;
  476.  
  477.     /*** remove all digipeaters before me ***/
  478.  
  479.     d = cp->hdr.nextdigi - 1;
  480.     if (d > 0) {
  481.       for (i = d; i < cp->hdr.ndigis; i++)
  482.         addrcp(cp->hdr.digis[i-d], cp->hdr.digis[i]);
  483.       cp->hdr.ndigis -= d;
  484.       cp->hdr.nextdigi = 1;
  485.     }
  486.  
  487.     /*** add necessary digipeaters and find interface ***/
  488.  
  489.     dest = cp->hdr.nextdigi < cp->hdr.ndigis ? cp->hdr.digis[cp->hdr.nextdigi] : cp->hdr.dest;
  490.     for (rp = ax_routeptr(dest, 0); rp; rp = rp->digi) {
  491.       if (rp->digi && cp->hdr.ndigis < MAXDIGIS) {
  492.         for (i = cp->hdr.ndigis - 1; i >= cp->hdr.nextdigi; i--)
  493.           addrcp(cp->hdr.digis[i+1], cp->hdr.digis[i]);
  494.         cp->hdr.ndigis++;
  495.         addrcp(cp->hdr.digis[cp->hdr.nextdigi], rp->digi->call);
  496.       }
  497.       cp->ifp = rp->ifp;
  498.     }
  499.     if (!cp->ifp) cp->ifp = axroute_default_ifp;
  500.  
  501.     /*** replace my address with hwaddr of interface ***/
  502.  
  503.     addrcp(cp->hdr.nextdigi ? cp->hdr.digis[0] : cp->hdr.source,
  504.            cp->ifp ? cp->ifp->hwaddr : Mycall);
  505.  
  506.   }
  507.  
  508.   cp->srtt = (ax_t1init * (1 + 2 * (cp->hdr.ndigis - cp->hdr.nextdigi))) / 2;
  509.   cp->mdev = cp->srtt / 4;
  510.   reset_t1(cp);
  511. }
  512.  
  513. /*---------------------------------------------------------------------------*/
  514.  
  515. static int  put_reseq(cp, bp, ns)
  516. struct ax25_cb *cp;
  517. struct mbuf *bp;
  518. int  ns;
  519. {
  520.  
  521.   char  *p;
  522.   int  cnt, sum;
  523.   struct axreseq *rp;
  524.   struct mbuf *tp;
  525.  
  526.   if (next_seq(ns) == cp->vr) return 0;
  527.   rp = &cp->reseq[ns];
  528.   if (rp->bp) return 0;
  529.   for (sum = 0, tp = bp; tp; tp = tp->next) {
  530.     cnt = tp->cnt;
  531.     p = tp->data;
  532.     while (cnt--) sum += uchar(*p++);
  533.   }
  534.   if (ns != cp->vr && sum == rp->sum) return 0;
  535.   rp->bp = bp;
  536.   rp->sum = sum;
  537.   return 1;
  538. }
  539.  
  540. /*---------------------------------------------------------------------------*/
  541.  
  542. int  lapb_input(iface, hdr, bp)
  543. struct iface *iface;
  544. struct ax25 *hdr;
  545. struct mbuf *bp;
  546. {
  547.  
  548.   int  cmdrsp;
  549.   int  control;
  550.   int  for_me;
  551.   int  nr;
  552.   int  ns;
  553.   int  pid;
  554.   int  type;
  555.   struct ax25_cb *cp;
  556.   struct ax25_cb *cpp;
  557.  
  558.   if (!bp) return (-1);
  559.   control = uchar(*bp->data);
  560.   type = ftype(control);
  561.   for_me = (ismyax25addr(hdr->dest) != NULLIF);
  562.  
  563.   if (!for_me &&
  564.       (type == UI ||
  565.        addreq(hdr->source, hdr->dest) ||
  566.        is_flexnet(hdr->source, 0) && is_flexnet(hdr->dest, 0))) {
  567.     struct mbuf *hbp;
  568.     if (!(hbp = htonax25(hdr, bp))) {
  569.       free_p(bp);
  570.       return (-1);
  571.     }
  572.     axroute(NULLAXCB, hbp);
  573.     return 0;
  574.   }
  575.  
  576.   (void) PULLCHAR(&bp);
  577.   if (bp) {
  578.     pid = uchar(*bp->data);
  579.     if (pid == PID_FLEXNET) is_flexnet(hdr->source, 1);
  580.   }
  581.  
  582.   switch (hdr->cmdrsp) {
  583.   case LAPB_COMMAND:
  584.     cmdrsp = DST_C | (control & PF);
  585.     break;
  586.   case LAPB_RESPONSE:
  587.     cmdrsp = SRC_C | (control & PF);
  588.     break;
  589.   default:
  590.     cmdrsp = VERS1;
  591.     break;
  592.   }
  593.  
  594.   for (cp = axcb_head; cp; cp = cp->next)
  595.     if (addreq(hdr->source, cp->hdr.dest) && addreq(hdr->dest, cp->hdr.source)) break;
  596.   if (!cp) {
  597.     if (for_me && netrom_server_axcb && isnetrom(hdr->source))
  598.       cp = create_axcb(netrom_server_axcb);
  599.     else if (for_me && axcb_server)
  600.       cp = create_axcb(axcb_server);
  601.     else
  602.       cp = create_axcb(NULLAXCB);
  603.     build_path(cp, iface, hdr, 1);
  604.     if (!for_me) {
  605.       cp->peer = cpp = create_axcb(NULLAXCB);
  606.       cpp->peer = cp;
  607.       build_path(cpp, NULLIF, hdr, 0);
  608.     } else
  609.       cpp = NULLAXCB;
  610.   } else
  611.     cpp = cp->peer;
  612.  
  613.   if (type == SABM) {
  614.     int  i;
  615.     build_path(cp, iface, hdr, 1);
  616.     if (cp->unack)
  617.       start_timer(&cp->timer_t1);
  618.     else
  619.       stop_timer(&cp->timer_t1);
  620.     stop_timer(&cp->timer_t2);
  621.     stop_timer(&cp->timer_t4);
  622.     cp->polling = 0;
  623.     cp->rnrsent = 0;
  624.     cp->rejsent = 0;
  625.     cp->remote_busy = 0;
  626.     cp->vr = 0;
  627.     cp->vs = cp->unack;
  628.     cp->retry = 0;
  629.     for (i = 0; i < 8; i++)
  630.       if (cp->reseq[i].bp) {
  631.         free_p(cp->reseq[i].bp);
  632.         cp->reseq[i].bp = 0;
  633.       }
  634.   }
  635.  
  636.   if (cp->mode == STREAM && type == I && pid != PID_NO_L3) {
  637.     cp->mode = DGRAM;
  638.     if (cpp) cpp->mode = DGRAM;
  639.   }
  640.  
  641.   set_timer(&cp->timer_t3, ax_t3init);
  642.   start_timer(&cp->timer_t3);
  643.  
  644.   switch (cp->state) {
  645.  
  646.   case DISCONNECTED:
  647.     if (for_me) {
  648.       if (type == SABM && cmdrsp != VERS1 && cp->r_upcall) {
  649.         send_packet(cp, UA, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  650.         setaxstate(cp, CONNECTED);
  651.       } else {
  652.         if (cmdrsp != RESP && cmdrsp != FINAL)
  653.           send_packet(cp, DM, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  654.         del_ax(cp);
  655.       }
  656.     } else {
  657.       if (type == SABM && cmdrsp != VERS1 && cpp->state == DISCONNECTED) {
  658.         setaxstate(cpp, CONNECTING);
  659.       } else if (type == SABM && cmdrsp != VERS1 && cpp->state == CONNECTING) {
  660.         build_path(cpp, NULLIF, hdr, 0);
  661.         send_packet(cpp, SABM, POLL, NULLBUF);
  662.       } else {
  663.         if (cmdrsp != RESP && cmdrsp != FINAL)
  664.           send_packet(cp, DM, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  665.         if (cpp->state == DISCONNECTED) {
  666.           del_ax(cpp);
  667.           del_ax(cp);
  668.         }
  669.       }
  670.     }
  671.     break;
  672.  
  673.   case CONNECTING:
  674.     switch (type) {
  675.     case I:
  676.     case RR:
  677.     case RNR:
  678.     case REJ:
  679.       break;
  680.     case SABM:
  681.       if (cmdrsp != VERS1) {
  682.         send_packet(cp, UA, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  683.         setaxstate(cp, CONNECTED);
  684.       }
  685.       break;
  686.     case UA:
  687.       if (cmdrsp != VERS1) {
  688.         setaxstate(cp, CONNECTED);
  689.       } else {
  690.         if (cpp && cpp->state == DISCONNECTED)
  691.           send_packet(cpp, DM, FINAL, NULLBUF);
  692.         cp->reason = RESET;
  693.         setaxstate(cp, DISCONNECTING);
  694.       }
  695.       break;
  696.     case DISC:
  697.       send_packet(cp, DM, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  698.     case DM:
  699.     case FRMR:
  700.       if (cpp && cpp->state == DISCONNECTED)
  701.         send_packet(cpp, DM, FINAL, NULLBUF);
  702.       cp->reason = RESET;
  703.       setaxstate(cp, DISCONNECTED);
  704.       break;
  705.     }
  706.     break;
  707.  
  708.   case CONNECTED:
  709.     switch (type) {
  710.     case I:
  711.     case RR:
  712.     case RNR:
  713.     case REJ:
  714.       stop_timer(&cp->timer_t1);
  715.       nr = control >> 5;
  716.       if (((cp->vs - nr) & 7) < cp->unack) {
  717.         if (!cp->polling) {
  718.           cp->retry = 0;
  719.           if (cp->sndtime[(nr-1)&7]) {
  720.             int32 rtt = msclock() - cp->sndtime[(nr-1)&7];
  721.             int32 abserr = (rtt > cp->srtt) ? rtt - cp->srtt : cp->srtt - rtt;
  722.             cp->srtt = ((AGAIN - 1) * cp->srtt + rtt + (AGAIN / 2)) / AGAIN;
  723.             cp->mdev = ((DGAIN - 1) * cp->mdev + abserr + (DGAIN / 2)) / DGAIN;
  724.             reset_t1(cp);
  725.             if (cp->cwind < ax_maxframe) {
  726.               cp->mdev += ((cp->srtt / cp->cwind) / 2);
  727.               cp->cwind++;
  728.             }
  729.           }
  730.         }
  731.         while (((cp->vs - nr) & 7) < cp->unack) {
  732.           cp->resndq = free_p(cp->resndq);
  733.           cp->unack--;
  734.         }
  735.         if (cpp && cpp->rnrsent && !busy(cpp)) send_ack(cpp, RESP);
  736.       }
  737.       if (type == I) {
  738.         if (for_me &&
  739.             pid == PID_NETROM &&
  740.             cp->r_upcall != netrom_server_axcb->r_upcall) {
  741.           new_neighbor(hdr->source);
  742.           setaxstate(cp, DISCONNECTING);
  743.           free_p(bp);
  744.           return 0;
  745.         }
  746.         ns = (control >> 1) & 7;
  747.         if (!bp) bp = alloc_mbuf(0);
  748.         if (put_reseq(cp, bp, ns))
  749.           while (bp = cp->reseq[cp->vr].bp) {
  750.             cp->reseq[cp->vr].bp = 0;
  751.             cp->vr = next_seq(cp->vr);
  752.             cp->rejsent = 0;
  753.             if (cp->mode == STREAM) (void) PULLCHAR(&bp);
  754.             if (for_me) {
  755.               cp->rcvcnt += len_p(bp);
  756.               if (cp->mode == STREAM)
  757.                 append(&cp->rcvq, bp);
  758.               else
  759.                 enqueue(&cp->rcvq, bp);
  760.             } else
  761.               send_ax(cpp, bp);
  762.           }
  763.         if (cmdrsp == POLL)
  764.           send_ack(cp, FINAL);
  765.         else {
  766.           set_timer(&cp->timer_t2, ax_t2init);
  767.           start_timer(&cp->timer_t2);
  768.         }
  769.         if (cp->r_upcall && cp->rcvcnt) (*cp->r_upcall)(cp, cp->rcvcnt);
  770.       } else {
  771.         if (cmdrsp == POLL) send_ack(cp, FINAL);
  772.         if (cp->polling && cmdrsp == FINAL) cp->retry = cp->polling = 0;
  773.         if (type == RNR) {
  774.           if (!cp->remote_busy) cp->remote_busy = msclock();
  775.           set_timer(&cp->timer_t4, ax_t4init);
  776.           start_timer(&cp->timer_t4);
  777.           cp->cwind = 1;
  778.         } else {
  779.           cp->remote_busy = 0;
  780.           stop_timer(&cp->timer_t4);
  781.           if (cp->unack && type == REJ) {
  782.             int  old_vs;
  783.             struct mbuf *bp1;
  784.             old_vs = cp->vs;
  785.             cp->vs = (cp->vs - cp->unack) & 7;
  786.             cp->sndtime[cp->vs] = 0;
  787.             dup_p(&bp1, cp->resndq, 0, MAXINT16);
  788.             send_packet(cp, I, CMD, bp1);
  789.             cp->vs = old_vs;
  790.             cp->cwind = 1;
  791.           } else if (cp->unack && cmdrsp == FINAL) {
  792.             struct mbuf *bp1, *qp;
  793.             cp->vs = (cp->vs - cp->unack) & 7;
  794.             for (qp = cp->resndq; qp; qp = qp->anext) {
  795.               cp->sndtime[cp->vs] = 0;
  796.               dup_p(&bp1, qp, 0, MAXINT16);
  797.               send_packet(cp, I, CMD, bp1);
  798.             }
  799.           }
  800.         }
  801.       }
  802.       try_send(cp, 1);
  803.       if (cp->polling || cp->unack && !cp->remote_busy)
  804.         start_timer(&cp->timer_t1);
  805.       if (cp->closed && !cp->sndq && !cp->unack ||
  806.           cp->remote_busy && msclock() - cp->remote_busy > 900000L)
  807.             setaxstate(cp, DISCONNECTING);
  808.       break;
  809.     case SABM:
  810.       send_packet(cp, UA, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  811.       try_send(cp, 1);
  812.       break;
  813.     case DISC:
  814.       send_packet(cp, DM, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  815.     case DM:
  816.       setaxstate(cp, DISCONNECTED);
  817.       break;
  818.     case UA:
  819.       cp->remote_busy = 0;
  820.       stop_timer(&cp->timer_t4);
  821.       if (cp->unack) start_timer(&cp->timer_t1);
  822.       try_send(cp, 1);
  823.       break;
  824.     case FRMR:
  825.       setaxstate(cp, DISCONNECTING);
  826.       break;
  827.     }
  828.     break;
  829.  
  830.   case DISCONNECTING:
  831.     switch (type) {
  832.     case I:
  833.     case RR:
  834.     case RNR:
  835.     case REJ:
  836.     case SABM:
  837.       if (cmdrsp != RESP && cmdrsp != FINAL)
  838.   
  839.       send_packet(cp, DM, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  840.       break;
  841.     case DISC:
  842.       send_packet(cp, DM, (cmdrsp == POLL) ? FINAL : RESP, NULLBUF);
  843.     case DM:
  844.     case UA:
  845.     case FRMR:
  846.       setaxstate(cp, DISCONNECTED);
  847.       break;
  848.     }
  849.     break;
  850.   }
  851.  
  852.   free_p(bp);
  853.   return 0;
  854. }
  855.  
  856. /*---------------------------------------------------------------------------*/
  857. /******************************* AX25 Commands *******************************/
  858. /*---------------------------------------------------------------------------*/
  859.  
  860. /* Control AX.25 digipeating */
  861.  
  862. static int  dodigipeat(argc, argv, p)
  863. int  argc;
  864. char  *argv[];
  865. void *p;
  866. {
  867.   return setintrc(&Digipeat, "Digipeat", argc, argv, 0, 2);
  868. }
  869.  
  870. /*---------------------------------------------------------------------------*/
  871.  
  872. /* Force a retransmission */
  873.  
  874. static int  doaxkick(argc, argv, p)
  875. int  argc;
  876. char  *argv[];
  877. void *p;
  878. {
  879.   struct ax25_cb *axp;
  880.  
  881.   axp = (struct ax25_cb *) ltop(htol(argv[1]));
  882.   if (!valid_ax(axp)) {
  883.     tprintf(Notval);
  884.     return 1;
  885.   }
  886.   kick_ax(axp);
  887.   return 0;
  888. }
  889.  
  890. /*---------------------------------------------------------------------------*/
  891.  
  892. /* Set maximum number of frames that will be allowed in flight */
  893.  
  894. static int  domaxframe(argc, argv, p)
  895. int  argc;
  896. char  *argv[];
  897. void *p;
  898. {
  899.   return setintrc(&ax_maxframe, "Maxframe", argc, argv, 1, 7);
  900. }
  901.  
  902. /*---------------------------------------------------------------------------*/
  903.  
  904. /* Display or change our AX.25 address */
  905.  
  906. static int  domycall(argc, argv, p)
  907. int  argc;
  908. char  *argv[];
  909. void *p;
  910. {
  911.   char  buf[15];
  912.  
  913.   if (argc < 2) {
  914.     pax25(buf, Mycall);
  915.     printf("Mycall %s\n", buf);
  916.   } else {
  917.     if (setcall(Mycall, argv[1]) == -1) return 1;
  918.     Mycall[ALEN] |= E;
  919.   }
  920.   return 0;
  921. }
  922.  
  923. /*---------------------------------------------------------------------------*/
  924.  
  925. /* Set maximum length of I-frame data field */
  926.  
  927. static int  dopaclen(argc, argv, p)
  928. int  argc;
  929. char  *argv[];
  930. void *p;
  931. {
  932.   return setintrc(&ax_paclen, "Paclen", argc, argv, 1, MAXINT16);
  933. }
  934.  
  935. /*---------------------------------------------------------------------------*/
  936.  
  937. /* Set size of I-frame above which polls will be sent after a timeout */
  938.  
  939. static int  dopthresh(argc, argv, p)
  940. int  argc;
  941. char  *argv[];
  942. void *p;
  943. {
  944.   return setintrc(&ax_pthresh, "Pthresh", argc, argv, 0, MAXINT16);
  945. }
  946.  
  947. /*---------------------------------------------------------------------------*/
  948.  
  949. /* Eliminate a AX25 connection */
  950.  
  951. static int  doaxreset(argc, argv, p)
  952. int  argc;
  953. char  *argv[];
  954. void *p;
  955. {
  956.   struct ax25_cb *cp;
  957.  
  958.   cp = (struct ax25_cb *) htol(argv[1]);
  959.   if (!valid_ax(cp)) {
  960.     printf(Notval);
  961.     return 1;
  962.   }
  963.   reset_ax(cp);
  964.   return 0;
  965. }
  966.  
  967. /*---------------------------------------------------------------------------*/
  968.  
  969. /* Set retry limit count */
  970.  
  971. static int  doretry(argc, argv, p)
  972. int  argc;
  973. char  *argv[];
  974. void *p;
  975. {
  976.   return setintrc(&ax_retry, "Retry", argc, argv, 0, MAXINT16);
  977. }
  978.  
  979. /*---------------------------------------------------------------------------*/
  980.  
  981. static int  dorouteadd(argc, argv, p)
  982. int  argc;
  983. char  *argv[];
  984. void *p;
  985. {
  986.  
  987.   char  tmp[AXALEN];
  988.   int  i, j, perm;
  989.   struct ax25 hdr;
  990.   struct iface *iface;
  991.  
  992.   argc--;
  993.   argv++;
  994.  
  995.   if (perm = !strcmp(*argv, "permanent")) {
  996.     argc--;
  997.     argv++;
  998.   }
  999.  
  1000.   if (!(iface = if_lookup(*argv))) {
  1001.     printf("Interface \"%s\" unknown\n", *argv);
  1002.     return 1;
  1003.   }
  1004.   if (iface->output != ax_output) {
  1005.     printf("Interface \"%s\" not kiss\n", *argv);
  1006.     return 1;
  1007.   }
  1008.   argc--;
  1009.   argv++;
  1010.  
  1011.   if (argc <= 0) {
  1012.     printf("Usage: ax25 route add [permanent] <interface> default|<path>\n");
  1013.     return 1;
  1014.   }
  1015.  
  1016.   if (!strcmp(*argv, "default")) {
  1017.     axroute_default_ifp = iface;
  1018.     return 0;
  1019.   }
  1020.  
  1021.   if (setcall(hdr.source, *argv)) {
  1022.     printf("Invalid call \"%s\"\n", *argv);
  1023.     return 1;
  1024.   }
  1025.   argc--;
  1026.   argv++;
  1027.  
  1028.   for (hdr.nextdigi = 0; argc > 0; argc--, argv++)
  1029.     if (strncmp("via", *argv, strlen(*argv))) {
  1030.       if (hdr.nextdigi >= MAXDIGIS) {
  1031.         printf("Too many digipeaters (max %d)\n", MAXDIGIS);
  1032.         return 1;
  1033.       }
  1034.       if (setcall(hdr.digis[hdr.nextdigi++], *argv)) {
  1035.         printf("Invalid call \"%s\"\n", *argv);
  1036.         return 1;
  1037.       }
  1038.     }
  1039.   for (i = 0, j = hdr.nextdigi - 1; i < j; i++, j--) {
  1040.     addrcp(tmp, hdr.digis[i]);
  1041.     addrcp(hdr.digis[i], hdr.digis[j]);
  1042.     addrcp(hdr.digis[j], tmp);
  1043.   }
  1044.  
  1045.   axroute_add(iface, &hdr, perm);
  1046.   return 0;
  1047. }
  1048.  
  1049. /*---------------------------------------------------------------------------*/
  1050.  
  1051. static void doroutelistentry(rp)
  1052. struct ax_route *rp;
  1053. {
  1054.  
  1055.   char  *cp, buf[1024];
  1056.   int  i, n;
  1057.   int  perm;
  1058.   struct ax_route *rp_stack[20];
  1059.   struct iface *ifp;
  1060.   struct tm *tm;
  1061.  
  1062.   tm = gmtime(&rp->time);
  1063.   pax25(cp = buf, rp->call);
  1064.   perm = rp->perm;
  1065.   for (n = 0; rp; rp = rp->digi) {
  1066.     rp_stack[++n] = rp;
  1067.     ifp = rp->ifp;
  1068.   }
  1069.   for (i = n; i > 1; i--) {
  1070.     strcat(cp, i == n ? " via " : ",");
  1071.     while (*cp) cp++;
  1072.     pax25(cp, rp_stack[i]->call);
  1073.   }
  1074.   printf("%2d-%.3s  %-9s  %c %s\n",
  1075.          tm->tm_mday,
  1076.          "JanFebMarAprMayJunJulAugSepOctNovDec" + 3 * tm->tm_mon,
  1077.          ifp ? ifp->name : "???",
  1078.          perm ? '*' : ' ',
  1079.          buf);
  1080. }
  1081.  
  1082. /*---------------------------------------------------------------------------*/
  1083.  
  1084. static int  doroutelist(argc, argv, p)
  1085. int  argc;
  1086. char  *argv[];
  1087. void *p;
  1088. {
  1089.  
  1090.   char  call[AXALEN];
  1091.   int  i;
  1092.   struct ax_route *rp;
  1093.  
  1094.   puts("Date    Interface  P Path");
  1095.   if (argc < 2) {
  1096.     for (i = 0; i < AXROUTESIZE; i++)
  1097.       for (rp = Ax_routes[i]; rp; rp = rp->next) doroutelistentry(rp);
  1098.     return 0;
  1099.   }
  1100.   argc--;
  1101.   argv++;
  1102.   for (; argc > 0; argc--, argv++)
  1103.     if (setcall(call, *argv) || !(rp = ax_routeptr(call, 0)))
  1104.       printf("*** Not in table *** %s\n", *argv);
  1105.     else
  1106.       doroutelistentry(rp);
  1107.   return 0;
  1108. }
  1109.  
  1110. /*---------------------------------------------------------------------------*/
  1111.  
  1112. static int doroutestat(argc, argv, p)
  1113. int argc;
  1114. char *argv[];
  1115. void *p;
  1116. {
  1117.  
  1118. #define NIFACES 128
  1119.  
  1120.   struct ifptable_t {
  1121.     struct iface *ifp;
  1122.     int count;
  1123.   };
  1124.  
  1125.   int dev;
  1126.   int i;
  1127.   int total;
  1128.   struct ax_route *dp;
  1129.   struct ax_route *rp;
  1130.   struct iface *ifp;
  1131.   struct ifptable_t ifptable[NIFACES];
  1132.  
  1133.   memset(ifptable, 0, sizeof(ifptable));
  1134.   for (dev = 0, ifp = Ifaces; ifp; dev++, ifp = ifp->next)
  1135.     ifptable[dev].ifp = ifp;
  1136.   for (i = 0; i < AXROUTESIZE; i++)
  1137.     for (rp = Ax_routes[i]; rp; rp = rp->next) {
  1138.       for (dp = rp; dp->digi; dp = dp->digi) ;
  1139.       if (dp->ifp)
  1140.         for (dev = 0; dev < NIFACES; dev++)
  1141.           if (ifptable[dev].ifp == dp->ifp) {
  1142.             ifptable[dev].count++;
  1143.             break;
  1144.           }
  1145.     }
  1146.   puts("Interface  Count");
  1147.   total = 0;
  1148.   for (dev = 0; dev < NIFACES; dev++) {
  1149.     if (ifptable[dev].count || ifptable[dev].ifp == axroute_default_ifp)
  1150.       printf("%c %-7s  %5d\n",
  1151.              ifptable[dev].ifp == axroute_default_ifp ? '*' : ' ',
  1152.              ifptable[dev].ifp->name,
  1153.              ifptable[dev].count);
  1154.     total += ifptable[dev].count;
  1155.   }
  1156.   puts("---------  -----");
  1157.   printf("  total    %5d\n", total);
  1158.   return 0;
  1159. }
  1160.  
  1161. /*---------------------------------------------------------------------------*/
  1162.  
  1163. static int  doaxroute(argc, argv, p)
  1164. int  argc;
  1165. char  *argv[];
  1166. void *p;
  1167. {
  1168.  
  1169.   static struct cmds routecmds[] = {
  1170.  
  1171.     "add",  dorouteadd,  0, 3, "ax25 route add [permanent] <interface> default|<path>",
  1172.     "list", doroutelist, 0, 0, NULLCHAR,
  1173.     "stat", doroutestat, 0, 0, NULLCHAR,
  1174.  
  1175.     NULLCHAR, NULLFP,    0, 0, NULLCHAR
  1176.   };
  1177.  
  1178.   axroute_loadfile();
  1179.   if (argc >= 2) return subcmd(routecmds, argc, argv, p);
  1180.   doroutestat(argc, argv, p);
  1181.   return 0;
  1182. }
  1183.  
  1184. /*---------------------------------------------------------------------------*/
  1185.  
  1186. /* Display AX.25 link level control blocks */
  1187.  
  1188. static int  doaxstatus(argc, argv, p)
  1189. int  argc;
  1190. char  *argv[];
  1191. void *p;
  1192. {
  1193.  
  1194.   int  i;
  1195.   struct ax25_cb *cp;
  1196.   struct mbuf *bp;
  1197.  
  1198.   if (argc < 2) {
  1199.     printf("   &AXCB Rcv-Q Unack  Rt  Srtt  State          Remote socket\n");
  1200.     for (cp = axcb_head; cp; cp = cp->next)
  1201.       printf("%8lx %5u%c%3u/%u%c %2d%6lu  %-13s  %s\n",
  1202.              (long) cp,
  1203.              cp->rcvcnt,
  1204.              cp->rnrsent ? '*' : ' ',
  1205.              cp->unack,
  1206.              cp->cwind,
  1207.              cp->remote_busy ? '*' : ' ',
  1208.              cp->retry,
  1209.              cp->srtt,
  1210.              ax25states[cp->state],
  1211.              ax25hdr_to_string(&cp->hdr));
  1212.     if (axcb_server)
  1213.       printf("%8lx                        Listen (S)     *\n",
  1214.              (long) axcb_server);
  1215.   } else {
  1216.     cp = (struct ax25_cb *) htol(argv[1]);
  1217.     if (!valid_ax(cp)) {
  1218.       printf("Not a valid control block address\n");
  1219.       return 1;
  1220.     }
  1221.     printf("Path:         %s\n", ax25hdr_to_string(&cp->hdr));
  1222.     printf("Interface:    %s\n", cp->ifp ? cp->ifp->name : "---");
  1223.     printf("State:        %s\n", (cp == axcb_server) ? "Listen (S)" : ax25states[cp->state]);
  1224.     if (cp->reason)
  1225.       printf("Reason:       %s\n", ax25reasons[cp->reason]);
  1226.     printf("Mode:         %s\n", (cp->mode == STREAM) ? "Stream" : "Dgram");
  1227.     printf("Closed:       %s\n", cp->closed ? "Yes" : "No");
  1228.     printf("Polling:      %s\n", cp->polling ? "Yes" : "No");
  1229.     printf("RNRsent:      %s\n", cp->rnrsent ? "Yes" : "No");
  1230.     printf("REJsent:      %s\n", cp->rejsent ? "Yes" : "No");
  1231.     if (cp->remote_busy)
  1232.       printf("Remote_busy:  %lu ms\n", msclock() - cp->remote_busy);
  1233.     else
  1234.       printf("Remote_busy:  No\n");
  1235.     printf("CWind:        %d\n", cp->cwind);
  1236.     printf("Retry:        %d\n", cp->retry);
  1237.     printf("Srtt:         %ld ms\n", cp->srtt);
  1238.     printf("Mean dev:     %ld ms\n", cp->mdev);
  1239.     tprintf("Timer T1:     ");
  1240.     if (run_timer(&cp->timer_t1))
  1241.       tprintf("%lu", read_timer(&cp->timer_t1));
  1242.     else
  1243.       tprintf("stop");
  1244.     tprintf("/%lu ms\n", dur_timer(&cp->timer_t1));
  1245.     tprintf("Timer T2:     ");
  1246.     if (run_timer(&cp->timer_t2))
  1247.       tprintf("%lu", read_timer(&cp->timer_t2));
  1248.     else
  1249.       tprintf("stop");
  1250.     tprintf("/%lu ms\n", dur_timer(&cp->timer_t2));
  1251.     tprintf("Timer T3:     ");
  1252.     if (run_timer(&cp->timer_t3))
  1253.       tprintf("%lu", read_timer(&cp->timer_t3));
  1254.     else
  1255.       tprintf("stop");
  1256.     tprintf("/%lu ms\n", dur_timer(&cp->timer_t3));
  1257.     tprintf("Timer T4:     ");
  1258.     if (run_timer(&cp->timer_t4))
  1259.       tprintf("%lu", read_timer(&cp->timer_t4));
  1260.     else
  1261.       tprintf("stop");
  1262.     tprintf("/%lu ms\n", dur_timer(&cp->timer_t4));
  1263.     tprintf("Timer T5:     ");
  1264.     if (run_timer(&cp->timer_t5))
  1265.       tprintf("%lu", read_timer(&cp->timer_t5));
  1266.     else
  1267.       tprintf("stop");
  1268.     tprintf("/%lu ms\n", dur_timer(&cp->timer_t5));
  1269.     printf("Rcv queue:    %d\n", cp->rcvcnt);
  1270.     if (cp->reseq[0].bp || cp->reseq[1].bp ||
  1271.         cp->reseq[2].bp || cp->reseq[3].bp ||
  1272.         cp->reseq[4].bp || cp->reseq[5].bp ||
  1273.         cp->reseq[6].bp || cp->reseq[7].bp) {
  1274.       printf("Reassembly queue:\n");
  1275.       for (i = next_seq(cp->vr); i != cp->vr; i = next_seq(i))
  1276.         if (cp->reseq[i].bp)
  1277.           printf("              Seq %3d: %3d bytes\n",
  1278.                  i, len_p(cp->reseq[i].bp));
  1279.     }
  1280.     printf("Snd queue:    %d\n", len_p(cp->sndq));
  1281.     if (cp->resndq) {
  1282.       printf("Resend queue:\n");
  1283.       for (i = 0, bp = cp->resndq; bp; i++, bp = bp->anext)
  1284.         printf("              Seq %3d: %3d bytes\n",
  1285.                (cp->vs - cp->unack + i) & 7, len_p(bp));
  1286.     }
  1287.   }
  1288.   return 0;
  1289. }
  1290.  
  1291. /*---------------------------------------------------------------------------*/
  1292.  
  1293. /* Set retransmission timer */
  1294.  
  1295. static int  dot1(argc, argv, p)
  1296. int  argc;
  1297. char  *argv[];
  1298. void *p;
  1299. {
  1300.   return setintrc(&ax_t1init, "T1 (ms)", argc, argv, 1, 0x7fffffff);
  1301. }
  1302.  
  1303. /*---------------------------------------------------------------------------*/
  1304.  
  1305. /* Set acknowledgement delay timer */
  1306.  
  1307. static int  dot2(argc, argv, p)
  1308. int  argc;
  1309. char  *argv[];
  1310. void *p;
  1311. {
  1312.   return setintrc(&ax_t2init, "T2 (ms)", argc, argv, 1, 0x7fffffff);
  1313. }
  1314.  
  1315. /*---------------------------------------------------------------------------*/
  1316.  
  1317. /* Set no-activity timer */
  1318.  
  1319. static int  dot3(argc, argv, p)
  1320. int  argc;
  1321. char  *argv[];
  1322. void *p;
  1323. {
  1324.   return setintrc(&ax_t3init, "T3 (ms)", argc, argv, 0, 0x7fffffff);
  1325. }
  1326.  
  1327. /*---------------------------------------------------------------------------*/
  1328.  
  1329. /* Set busy timer */
  1330.  
  1331. static int  dot4(argc, argv, p)
  1332. int  argc;
  1333. char  *argv[];
  1334. void *p;
  1335. {
  1336.   return setintrc(&ax_t4init, "T4 (ms)", argc, argv, 1, 0x7fffffff);
  1337. }
  1338.  
  1339. /*---------------------------------------------------------------------------*/
  1340.  
  1341. /* Set packet assembly timer */
  1342.  
  1343. static int  dot5(argc, argv, p)
  1344. int  argc;
  1345. char  *argv[];
  1346. void *p;
  1347. {
  1348.   return setintrc(&ax_t5init, "T5 (ms)", argc, argv, 1, 0x7fffffff);
  1349. }
  1350.  
  1351. /*---------------------------------------------------------------------------*/
  1352.  
  1353. /* Set high water mark on receive queue that triggers RNR */
  1354.  
  1355. static int  doaxwindow(argc, argv, p)
  1356. int  argc;
  1357. char  *argv[];
  1358. void *p;
  1359. {
  1360.   return setintrc(&ax_window, "Window", argc, argv, 1, MAXINT16);
  1361. }
  1362.  
  1363. /*---------------------------------------------------------------------------*/
  1364.  
  1365. /* Multiplexer for top-level ax25 command */
  1366.  
  1367. int  doax25(argc, argv, p)
  1368. int  argc;
  1369. char  *argv[];
  1370. void *p;
  1371. {
  1372.  
  1373.   static struct cmds axcmds[] = {
  1374.  
  1375.     "digipeat", dodigipeat, 0, 0, NULLCHAR,
  1376.     "kick",     doaxkick,   0, 2, "ax25 kick <axcb>",
  1377.     "maxframe", domaxframe, 0, 0, NULLCHAR,
  1378.     "mycall",   domycall,   0, 0, NULLCHAR,
  1379.     "paclen",   dopaclen,   0, 0, NULLCHAR,
  1380.     "pthresh",  dopthresh,  0, 0, NULLCHAR,
  1381.     "reset",    doaxreset,  0, 2, "ax25 reset <axcb>",
  1382.     "retry",    doretry,    0, 0, NULLCHAR,
  1383.     "route",    doaxroute,  0, 0, NULLCHAR,
  1384.     "status",   doaxstatus, 0, 0, NULLCHAR,
  1385.     "t1",       dot1,       0, 0, NULLCHAR,
  1386.     "t2",       dot2,       0, 0, NULLCHAR,
  1387.     "t3",       dot3,       0, 0, NULLCHAR,
  1388.     "t4",       dot4,       0, 0, NULLCHAR,
  1389.     "t5",       dot5,       0, 0, NULLCHAR,
  1390.     "window",   doaxwindow, 0, 0, NULLCHAR,
  1391.  
  1392.     NULLCHAR,   NULLFP,     0, 0, NULLCHAR
  1393.   };
  1394.  
  1395.   return subcmd(axcmds, argc, argv, p);
  1396. }
  1397.  
  1398. /*---------------------------------------------------------------------------*/
  1399. /***************************** User Calls to AX25 ****************************/
  1400. /*---------------------------------------------------------------------------*/
  1401.  
  1402. struct ax25_cb *open_ax(path, mode, r_upcall, t_upcall, s_upcall, user)
  1403. char  *path;
  1404. int  mode;
  1405. void (*r_upcall) __ARGS((struct ax25_cb *p, int cnt));
  1406. void (*t_upcall) __ARGS((struct ax25_cb *p, int cnt));
  1407. void (*s_upcall) __ARGS((struct ax25_cb *p, int oldstate, int newstate));
  1408. char  *user;
  1409. {
  1410.  
  1411.   char  *ap;
  1412.   struct ax25 hdr;
  1413.   struct ax25_cb *cp;
  1414.  
  1415.   switch (mode) {
  1416.   case AX_ACTIVE:
  1417.     hdr.ndigis = hdr.nextdigi = 0;
  1418.     ap = path;
  1419.     addrcp(hdr.dest, ap);
  1420.     ap += AXALEN;
  1421.     addrcp(hdr.source, ap);
  1422.     ap += AXALEN;
  1423.     while (!(ap[-1] & E)) {
  1424.       addrcp(hdr.digis[hdr.ndigis++], ap);
  1425.       ap += AXALEN;
  1426.     }
  1427.     for (cp = axcb_head; cp; cp = cp->next)
  1428.       if (!cp->peer && addreq(hdr.dest, cp->hdr.dest)) {
  1429.         Net_error = CON_EXISTS;
  1430.         return NULLAXCB;
  1431.       }
  1432.     if (!(cp = create_axcb(NULLAXCB))) {
  1433.       Net_error = NO_MEM;
  1434.       return NULLAXCB;
  1435.     }
  1436.     build_path(cp, NULLIF, &hdr, 0);
  1437.     cp->r_upcall = r_upcall;
  1438.     cp->t_upcall = t_upcall;
  1439.     cp->s_upcall = s_upcall;
  1440.     cp->user = user;
  1441.     setaxstate(cp, CONNECTING);
  1442.     return cp;
  1443.   case AX_SERVER:
  1444.     if (!(cp = (struct ax25_cb *) cxallocw(1, sizeof(struct ax25_cb )))) {
  1445.       Net_error = NO_MEM;
  1446.       return NULLAXCB;
  1447.     }
  1448.     cp->r_upcall = r_upcall;
  1449.     cp->t_upcall = t_upcall;
  1450.     cp->s_upcall = s_upcall;
  1451.     cp->user = user;
  1452.     return cp;
  1453.   default:
  1454.     Net_error = INVALID;
  1455.     return NULLAXCB;
  1456.   }
  1457. }
  1458.  
  1459. /*---------------------------------------------------------------------------*/
  1460.  
  1461. int  send_ax(cp, bp)
  1462. struct ax25_cb *cp;
  1463. struct mbuf *bp;
  1464. {
  1465.   int cnt;
  1466.  
  1467.   if (!(cp && bp)) {
  1468.     free_p(bp);
  1469.     Net_error = INVALID;
  1470.     return (-1);
  1471.   }
  1472.   switch (cp->state) {
  1473.   case DISCONNECTED:
  1474.     free_p(bp);
  1475.     Net_error = NO_CONN;
  1476.     return (-1);
  1477.   case CONNECTING:
  1478.   case CONNECTED:
  1479.     if (!cp->closed) {
  1480.       if (cnt = len_p(bp)) {
  1481.         if (cp->mode == STREAM)
  1482.           append(&cp->sndq, bp);
  1483.         else
  1484.           enqueue(&cp->sndq, bp);
  1485.         cp->sndqtime = msclock();
  1486.         try_send(cp, 0);
  1487.       }
  1488.       return cnt;
  1489.     }
  1490.   case DISCONNECTING:
  1491.     free_p(bp);
  1492.     Net_error = CON_CLOS;
  1493.     return (-1);
  1494.   }
  1495.   return (-1);
  1496. }
  1497.  
  1498. /*---------------------------------------------------------------------------*/
  1499.  
  1500. int  space_ax(cp)
  1501. struct ax25_cb *cp;
  1502. {
  1503.   int  cnt;
  1504.  
  1505.   if (!cp) {
  1506.     Net_error = INVALID;
  1507.     return (-1);
  1508.   }
  1509.   switch (cp->state) {
  1510.   case DISCONNECTED:
  1511.     Net_error = NO_CONN;
  1512.     return (-1);
  1513.   case CONNECTING:
  1514.   case CONNECTED:
  1515.     if (!cp->closed) {
  1516.       cnt = (cp->cwind - cp->unack) * ax_paclen - len_p(cp->sndq);
  1517.       return (cnt > 0) ? cnt : 0;
  1518.     }
  1519.   case DISCONNECTING:
  1520.     Net_error = CON_CLOS;
  1521.     return (-1);
  1522.   }
  1523.   return (-1);
  1524. }
  1525.  
  1526. /*---------------------------------------------------------------------------*/
  1527.  
  1528. int  recv_ax(cp, bpp, cnt)
  1529. struct ax25_cb *cp;
  1530. struct mbuf **bpp;
  1531. int cnt;
  1532. {
  1533.   if (!(cp && bpp)) {
  1534.     Net_error = INVALID;
  1535.     return (-1);
  1536.   }
  1537.   if (cp->rcvcnt) {
  1538.     if (cp->mode == DGRAM || !cnt || cp->rcvcnt <= cnt) {
  1539.       *bpp = dequeue(&cp->rcvq);
  1540.       cnt = len_p(*bpp);
  1541.     } else {
  1542.       if (!(*bpp = alloc_mbuf(cnt))) {
  1543.         Net_error = NO_MEM;
  1544.         return (-1);
  1545.       }
  1546.       pullup(&cp->rcvq, (*bpp)->data, cnt);
  1547.       (*bpp)->cnt = cnt;
  1548.     }
  1549.     cp->rcvcnt -= cnt;
  1550.     if (cp->rnrsent && !busy(cp)) send_ack(cp, RESP);
  1551.     return cnt;
  1552.   }
  1553.   switch (cp->state) {
  1554.   case CONNECTING:
  1555.   case CONNECTED:
  1556.     *bpp = NULLBUF;
  1557.     Net_error = WOULDBLK;
  1558.     return (-1);
  1559.   case DISCONNECTED:
  1560.   case DISCONNECTING:
  1561.     *bpp = NULLBUF;
  1562.     return 0;
  1563.   }
  1564.   return (-1);
  1565. }
  1566.  
  1567. /*---------------------------------------------------------------------------*/
  1568.  
  1569. int  close_ax(cp)
  1570. struct ax25_cb *cp;
  1571. {
  1572.   if (!cp) {
  1573.     Net_error = INVALID;
  1574.     return (-1);
  1575.   }
  1576.   if (cp->closed) {
  1577.     Net_error = CON_CLOS;
  1578.     return (-1);
  1579.   }
  1580.   cp->closed = 1;
  1581.   switch (cp->state) {
  1582.   case DISCONNECTED:
  1583.     Net_error = NO_CONN;
  1584.     return (-1);
  1585.   case CONNECTING:
  1586.     setaxstate(cp, DISCONNECTED);
  1587.     return 0;
  1588.   case CONNECTED:
  1589.     if (!cp->sndq && !cp->unack) setaxstate(cp, DISCONNECTING);
  1590.     return 0;
  1591.   case DISCONNECTING:
  1592.     Net_error = CON_CLOS;
  1593.     return (-1);
  1594.   }
  1595.   return (-1);
  1596. }
  1597.  
  1598. /*---------------------------------------------------------------------------*/
  1599.  
  1600. int  reset_ax(cp)
  1601. struct ax25_cb *cp;
  1602. {
  1603.   if (!cp) {
  1604.     Net_error = INVALID;
  1605.     return (-1);
  1606.   }
  1607.   if (cp == axcb_server) {
  1608.     free(axcb_server);
  1609.     axcb_server = NULLAXCB;
  1610.     return 0;
  1611.   }
  1612.   cp->reason = RESET;
  1613.   setaxstate(cp, DISCONNECTED);
  1614.   return 0;
  1615. }
  1616.  
  1617. /*---------------------------------------------------------------------------*/
  1618.  
  1619. int  del_ax(cp)
  1620. struct ax25_cb *cp;
  1621. {
  1622.  
  1623.   int  i;
  1624.   struct ax25_cb *p, *q;
  1625.  
  1626.   for (q = 0, p = axcb_head; p != cp; q = p, p = p->next)
  1627.     if (!p) {
  1628.       Net_error = INVALID;
  1629.       return (-1);
  1630.     }
  1631.   if (q)
  1632.     q->next = p->next;
  1633.   else
  1634.     axcb_head = p->next;
  1635.   stop_timer(&cp->timer_t1);
  1636.   stop_timer(&cp->timer_t2);
  1637.   stop_timer(&cp->timer_t3);
  1638.   stop_timer(&cp->timer_t4);
  1639.   stop_timer(&cp->timer_t5);
  1640.   for (i = 0; i < 8; i++) free_p(cp->reseq[i].bp);
  1641.   free_q(&cp->rcvq);
  1642.   free_q(&cp->sndq);
  1643.   free_q(&cp->resndq);
  1644.   free(cp);
  1645.   return 0;
  1646. }
  1647.  
  1648. /*---------------------------------------------------------------------------*/
  1649.  
  1650. int  valid_ax(cp)
  1651. struct ax25_cb *cp;
  1652. {
  1653.   struct ax25_cb *p;
  1654.  
  1655.   if (!cp) return 0;
  1656.   if (cp == axcb_server) return 1;
  1657.   for (p = axcb_head; p; p = p->next)
  1658.     if (p == cp) return 1;
  1659.   return 0;
  1660. }
  1661.  
  1662. /*---------------------------------------------------------------------------*/
  1663.  
  1664. /* Force a retransmission */
  1665.  
  1666. int  kick_ax(axp)
  1667. struct ax25_cb *axp;
  1668. {
  1669.   if (!valid_ax(axp)) return -1;
  1670.   t1_timeout(axp);
  1671.   return 0;
  1672. }
  1673.  
  1674.